﻿using System;
using System.Globalization;
using System.Linq;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Index;

namespace Medianamik.Core.Index
{
	public class Indexer
	{

        public void ReIndexAll()
        {
            var instances = NodeTypeManager.GetAllTypes(false)
                .Where(t => t.Indexable)
                .SelectMany(t => NodeManager.GetNodesByType(t.ID, true))
                .SelectMany(n => n.Instances);

            var factory = new DocumentFactory();
            var w = GetIndexWriter(true);
            try
            {
                foreach (var ni in instances)
                {
                    Index(ni, factory,w);
                }
            }
            finally
            {
                if (w != null) w.Close();
            }
        }
                

		internal void Index(NodeInstance pNodeInstance, DocumentFactory pFactory)
		{
			var r = GetIndexReader();
			try
			{
                Remove(pNodeInstance.Node.ID, pNodeInstance.Culture, r);
				
			}
			finally
			{
				if (r != null) r.Close();
			}
            var d = pFactory.Create(pNodeInstance);
            var w = GetIndexWriter();
            try
            {
                Index(pNodeInstance, pFactory, w);

            }
            finally
            {
                if (w != null) w.Close();
            }

			
		}
        private static void Index(NodeInstance pNodeInstance, DocumentFactory pFactory, IndexWriter pWriter)
        {
            var d = pFactory.Create(pNodeInstance);
            pWriter.AddDocument(d);
        }


		internal void Remove(Guid pNodeId, CultureInfo pCulture)
		{
			var r = GetIndexReader();
            try
			{
				Remove(pNodeId,pCulture,r);
			}
			finally
			{
				if (r != null) { r.Close(); }
			}
		}

        private static void Remove(Guid pNodeId, CultureInfo pCulture, IndexReader pReader)
        {
            if (pReader != null)
            {
                pReader.DeleteDocuments(new Term("Key", IndexUtils.GetDocumentKey(pNodeId, pCulture.Name)));
            }
        }

        private static IndexWriter GetIndexWriter()
        {
            return GetIndexWriter(new System.IO.DirectoryInfo(IndexUtils.IndexDirectoryPath).GetFiles().Length <= 1);
        }

	    private static IndexWriter GetIndexWriter(bool create)
		{
            EnsureDirectory();
            return new IndexWriter(IndexUtils.IndexDirectory, new StandardAnalyzer(IndexUtils.EngineVersion), create, IndexWriter.MaxFieldLength.UNLIMITED);
		}
		internal  IndexReader GetIndexReader()
		{
            EnsureDirectory();
            return new System.IO.DirectoryInfo(IndexUtils.IndexDirectoryPath).GetFiles().Length > 1 
                 ? IndexReader.Open(IndexUtils.IndexDirectory, true) 
                 : null;
		}

        private static void EnsureDirectory()
        {
            if (!System.IO.Directory.Exists(IndexUtils.IndexDirectoryPath))
            {
                System.IO.Directory.CreateDirectory(IndexUtils.IndexDirectoryPath);
            }
        }

		
	}
}

